package com.neuedu.demoweb.web.controller;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.neuedu.demoweb.bean.Admin;
import com.neuedu.demoweb.common.Pager;
import com.neuedu.demoweb.common.Result;
import com.neuedu.demoweb.common.WebException;
import com.neuedu.demoweb.service.AdminService;
import com.neuedu.demoweb.service.impl.AdminServiceImpl;
import com.neuedu.demoweb.utils.PasswordUtils;
import com.neuedu.demoweb.utils.WebConstants;
import com.neuedu.demoweb.utils.WebUtil;
import com.neuedu.demoweb.web.framework.ServletController;

/**
 * 
 * @author chens
 *
 */
public class AdminController implements ServletController {
	private AdminService adminService = null;

	public AdminController() {
		super();
		this.adminService = new AdminServiceImpl();
	}

	@Override
	public synchronized void doService(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 先获取操作名称
		String action = WebUtil.getAction(request);
		switch (action) {
		case WebConstants.ACTION_SEARCH:
			// 根据操作名称调用不同的操作方法
			search(request, response);
			break;
		case WebConstants.ACTION_ADD:
			add(request, response);
			break;
		case WebConstants.ACTION_EDIT:
			edit(request, response);
			break;
		case WebConstants.ACTION_DEL:
			delete(request, response);
			break;
		case WebConstants.ACTION_LOGIN:
			login(request, response);
			break;
		case WebConstants.ACTION_UPDATE_PASSWORD:
			updatePassword(request, response);
			break;
		case WebConstants.ACTION_LOGOUT:
			logout(request, response);
			break;
		default:
			// 错误操作返回show.jsp
			response.sendRedirect(request.getContextPath() + "/show.jsp");
			break;
		}
	}

	private void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 使用会话失效，取消所有会话跟踪信息
		request.getSession().invalidate();
		response.sendRedirect(request.getContextPath() + "/login.html");
	}

	private void updatePassword(HttpServletRequest request, HttpServletResponse response) throws IOException {

		String password = request.getParameter("opassword");
		String npassword = request.getParameter("npassword");

		Admin admin = (Admin) request.getSession().getAttribute("login_user");

		Result result = new Result();
		try {
			// 先校验原密码，通过后才能修改密码
			if (admin != null && PasswordUtils.matches(admin.getSalt(), password, admin.getPassword())) {
				// 更新密码时，同时更新盐值和重新加密密码
				String salt = PasswordUtils.getSalt();
				password = PasswordUtils.encode(npassword, salt);
				admin.setPassword(password);
				admin.setSalt(salt);

				boolean ret = adminService.edit(admin);
				if (ret) {
					result.setSuccess(true);
				} else {
					result.setErrorMsg("修改管理员失败");
				}
			} else {
				result.setErrorMsg("原密码不正确");
			}

		} catch (WebException e) {
			e.printStackTrace();
			result.setErrorMsg(e.getMessage());
		}
		WebUtil.writeJsonToClient(response, result);

	}

	private void login(HttpServletRequest request, HttpServletResponse response) throws IOException {

		String adminName = request.getParameter("adminName");
		String password = request.getParameter("password");
		String validate = request.getParameter("validate");

		Admin param = new Admin(null, adminName, password);
		try {
			String rand = (String) request.getSession().getAttribute("rand");
			// 使用验证码技术后，需要先校验验证码是否正确，在进行数据库校验；避免系统被机器暴露破解
			if (rand != null && rand.equals(validate)) {
				Admin temp = adminService.login(param);

				// 进行md5+盐值算法判断
				if (temp != null && PasswordUtils.matches(temp.getSalt(), password, temp.getPassword())) {
					param.setAdminId(temp.getAdminId());
					// 数据库验证成功，保存用户的session会话跟踪中
					request.getSession().setAttribute("login_user", temp);

					// 用户登录成功后，使用cookie返回登录用户名称给客户端
					Cookie cookie = new Cookie("login_user", temp.getAdminName());
					cookie.setPath("/");
					response.addCookie(cookie);
				}
			}

		} catch (WebException e) {
			e.printStackTrace();
		}

		WebUtil.writeJsonToClient(response, param);
	}

	private void delete(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String adminIdString = request.getParameter("adminId");
		Integer adminId = Integer.valueOf(adminIdString);
		Result result = new Result();

		if (adminId != null && adminId == 1) {
			result.setSuccess(false);
			result.setErrorMsg("超级管理员不能删除 ");
		} else {
			try {
				boolean ret = adminService.deleteById(adminId);
				if (ret) {
					result.setSuccess(true);
				} else {
					result.setErrorMsg("删除管理员失败");
				}
			} catch (WebException e) {
				e.printStackTrace();
				result.setErrorMsg(e.getMessage());
			}
		}

		WebUtil.writeJsonToClient(response, result);
	}

	private void edit1(HttpServletRequest request, HttpServletResponse response) throws IOException {

		String adminIdString = request.getParameter("adminId");
		String adminName = request.getParameter("adminName");
		String rawPassword = request.getParameter("password");

		Integer adminId = Integer.valueOf(adminIdString);

		Result result = new Result();
		try {

			Admin admin = adminService.findById(adminId);

			if (admin != null) {
				// 修改用户时，同时更新盐值和重新加密密码
				String salt = PasswordUtils.getSalt();
				String password = PasswordUtils.encode(rawPassword, salt);
				admin.setAdminName(adminName);
				admin.setSalt(salt);
				admin.setPassword(password);

				boolean ret = adminService.edit(admin);
				if (ret) {
					result.setSuccess(true);
				} else {
					result.setErrorMsg("修改管理员失败");
				}
			} else {
				result.setErrorMsg("数据不存在");
			}

		} catch (WebException e) {
			e.printStackTrace();
			result.setErrorMsg(e.getMessage());
		}
		WebUtil.writeJsonToClient(response, result);
	}

	private void edit(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Result result = new Result();

		String adminIdString = request.getParameter("adminId");
		Integer adminId = Integer.valueOf(adminIdString);
		Admin admin = adminService.findById(adminId);

		// 图片存放路径
		String relpath = "uploads";
		String path = request.getServletContext().getRealPath(relpath);
		String newFileName = null;
		// 实例化本地磁盘工厂
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// 实例化文件上传类
		ServletFileUpload upload = new ServletFileUpload(factory);
		// 处理中文问题
		upload.setHeaderEncoding("UTF-8");
		// 设置全部文件上传的最大值
		upload.setFileSizeMax(Integer.valueOf(100) * 1024 * 1024);// 单文件100M
		upload.setSizeMax(Integer.valueOf(1024) * 1024 * 1024); // 最多1G

		try {
			List<FileItem> fileItems = upload.parseRequest(request); // 解码请求 得到所有表单元素
			for (FileItem item : fileItems) {

				// 表单内容是分块上传，上传内容有可能是文件，也可能是普通文字
				if (item.isFormField()) { // 这个选项是文字
					// 获取字段名
					String fieldName = item.getFieldName();
					// 获取字段值 括号内的参数不可少否则乱码
					String value = item.getString("UTF-8");
					switch (fieldName) {
					case "adminName":
						admin.setAdminName(value);
						break;
					case "password":
						// 修改用户时，更新随机盐值，并加密密码
						String salt = PasswordUtils.getSalt();
						String password = PasswordUtils.encode(value, salt);
						admin.setSalt(salt);
						admin.setPassword(password);
						break;
					default:
						break;
					}
				} else {
					// 是文件
					// 获取图片后缀名
					String format = item.getName().substring(item.getName().indexOf("."), item.getName().length());
					// 图片命名
					newFileName = UUID.randomUUID().toString().replaceAll("-", "") + format;
					System.out.println("文件名是：" + newFileName); // 文件名
					item.write(new File(path, newFileName));
					// 头像在服务存储的相 对地址
					String imgpath = "uploads/" + newFileName;
					admin.setAdminImage(imgpath);
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		try {

			boolean ret = adminService.edit(admin);
			if (ret) {
				result.setSuccess(true);
			} else {
				result.setErrorMsg("修改管理员失败");
			}
		} catch (WebException e) {
			e.printStackTrace();
			result.setErrorMsg("修改管理员失败");
		}

		WebUtil.writeJsonToClient(response, result);

	}

	private void add(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Result result = new Result();
		Admin object = new Admin();
		// 图片存放路径
		String relpath = "uploads";
		String path = request.getServletContext().getRealPath(relpath);
		String newFileName = null;
		// 实例化本地磁盘工厂
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// 实例化文件上传类
		ServletFileUpload upload = new ServletFileUpload(factory);
		// 处理中文问题
		upload.setHeaderEncoding("UTF-8");
		// 设置全部文件上传的最大值
		upload.setFileSizeMax(Integer.valueOf(100) * 1024 * 1024);// 单文件100M
		upload.setSizeMax(Integer.valueOf(1024) * 1024 * 1024); // 最多1G

		try {
			List<FileItem> fileItems = upload.parseRequest(request); // 解码请求 得到所有表单元素
			for (FileItem item : fileItems) {

				// 表单内容是分块上传，上传内容有可能是文件，也可能是普通文字
				if (item.isFormField()) { // 这个选项是文字
					// 获取字段名
					String fieldName = item.getFieldName();
					// 获取字段值 括号内的参数不可少否则乱码
					String value = item.getString("UTF-8");

					switch (fieldName) {
					case "adminName":
						object.setAdminName(value);
						break;
					case "password":
						// 新增用户时，生成随机盐值，并加密密码
						String salt = PasswordUtils.getSalt();
						String password = PasswordUtils.encode(value, salt);
						object.setSalt(salt);
						object.setPassword(password);
						break;
					default:
						break;
					}
				} else {
					// 是文件
					// 获取图片后缀名
					String format = item.getName().substring(item.getName().indexOf("."), item.getName().length());
					// 图片命名
					newFileName = UUID.randomUUID().toString().replaceAll("-", "") + format;
					System.out.println("文件名是：" + newFileName); // 文件名
					item.write(new File(path, newFileName));
					// 头像在服务存储的相 对地址
					String imgpath = "uploads/" + newFileName;

					object.setAdminImage(imgpath);
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			
			
			boolean ret = adminService.add(object);
			if (ret) {
				result.setSuccess(true);
			} else {
				result.setErrorMsg("新增管理员失败");
			}
		} catch (WebException e) {
			e.printStackTrace();
			result.setErrorMsg("新增管理员失败");
		}

		WebUtil.writeJsonToClient(response, result);

	}

	/**
	 * 分页查询操作,前后端分离需要返回json数据结构
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	private void search(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 获取easyui框架提交的分页查询,参数名默认是page和rows
		String strPage = request.getParameter("page");
		String strRows = request.getParameter("rows");
		System.out.println(strPage + " :::   " + strRows);
		int page = 1;
		int size = 10;
		if (strPage != null) {
			page = Integer.valueOf(strPage);
		}
		if (strRows != null) {
			size = Integer.valueOf(strRows);
		}
		Pager<Admin> pager = new Pager<>(page, size);
		List<Admin> list = adminService.search(pager);
		int total = adminService.findTotal(pager);
		// 使用pager对象返回数据给浏览器，先把查询到的数据绑定到pager对象
		pager.setRows(list);
		pager.setTotal(total);

		WebUtil.writeJsonToClient(response, pager);
	}
}
